<?php

namespace app\common\helper;

use OSS\Core\OssException;
use OSS\Core\OssUtil;
use OSS\OssClient;

class AliOss
{
    protected $oss;
    protected $bucket;
    protected $endpoint;
    protected $domain;

    public function __construct()
    {
        $config = cache('config');
        $this->bucket = $config['ali_oss_Bucket'];
        $this->endpoint = $config['ali_oss_endpoint'];
        $this->oss = new OssClient($config['ali_oss_accessKeyId'], $config['ali_oss_accessKeySecret'], $this->endpoint);
    }

    public function upload($path,$file,$id)
    {
        try {
            $back_url = "https://ai.phpve.com/index/callback/ossCallBack";
            $url['callbackUrl'] = $back_url;
            $url['callbackBody'] = 'bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&my_var1=${x:var_id}';
            $var['x:var_id'] = (string) $id;
            $options[OssClient::OSS_CALLBACK] = json_encode($url);
            $options[OssClient::OSS_CALLBACK_VAR] = json_encode($var);
            return $this->oss->uploadFile($this->bucket, $path,$file,$options);
        } catch (OssException $e) {
            writeLog($e->getMessage());
            return  false;
        }
    }

    public function del($paths)
    {
        $this->oss->deleteObjects($this->bucket,$paths);
    }

    public function multiUploadFile($path,$file,$id = null)
    {
        return $this->_multiUploadFile($path,$file,$id);
    }


    protected function _multiUploadFile($path,$file,$id)
    {
        if (!$id) $id = "xx";
        $partSize = 10 * 1024 * 1024;
        $uploadFileSize = sprintf('%u',filesize($file));
        if ($uploadFileSize < $partSize) {
            return  $this->upload($path,$file,$id);
        }

        $uploadId = $this->oss->initiateMultipartUpload($this->bucket,$path);
        $pieces = $this->oss->generateMultiuploadParts($uploadFileSize, $partSize);
        $responseUploadPart = array();
        $uploadPosition = 0;
        $isCheckMd5 = true;
        foreach ($pieces as $i => $piece) {
            $fromPos = $uploadPosition + (integer)$piece[$this->oss::OSS_SEEK_TO];
            $toPos = (integer)$piece[$this->oss::OSS_LENGTH] + $fromPos - 1;
            $upOptions = array(
                $this->oss::OSS_FILE_UPLOAD => $file,
                $this->oss::OSS_PART_NUM => ($i + 1),
                $this->oss::OSS_SEEK_TO => $fromPos,
                $this->oss::OSS_LENGTH => $toPos - $fromPos + 1,
                $this->oss::OSS_CHECK_MD5 => $isCheckMd5,
            );
            // MD5校验。
            if ($isCheckMd5) {
                $contentMd5 = OssUtil::getMd5SumForFile($file, $fromPos, $toPos);
                $upOptions[$this->oss::OSS_CONTENT_MD5] = $contentMd5;
            }
            try {
                // 上传分片。
                $responseUploadPart[] = $this->oss->uploadPart($this->bucket, $path, $uploadId, $upOptions);
            } catch(OssException $e) {
                writeLog($e->getMessage());
            }
        }
        // $uploadParts是由每个分片的ETag和分片号（PartNumber）组成的数组。
        $uploadParts = array();
        foreach ($responseUploadPart as $i => $eTag) {
            $uploadParts[] = array(
                'PartNumber' => ($i + 1),
                'ETag' => $eTag,
            );
        }

        $back_url =  "https://ai.phpve.com/index/callback/ossCallBack";
        $url['callbackUrl'] = $back_url;
        $url['callbackBody'] = 'bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&my_var1=${x:var_id}';
        $var['x:var_id'] = (string) $id;
        $options[OssClient::OSS_CALLBACK] = json_encode($url);
        $options[OssClient::OSS_CALLBACK_VAR] = json_encode($var);
        try {
            return $this->oss->completeMultipartUpload($this->bucket, $path, $uploadId, $uploadParts, $options);
        } catch(OssException $e) {
            writeLog($e->getMessage() . "----" . "\r\n");
            return  false;
        }

    }
}